<!--
 - Copyright 2022. Huawei Technologies Co., Ltd. All rights reserved.

 - Licensed under the Apache License, Version 2.0 (the "License");
 - you may not use this file except in compliance with the License.
 - You may obtain a copy of the License at

 -   http://www.apache.org/licenses/LICENSE-2.0

 - Unless required by applicable law or agreed to in writing, software
 - distributed under the License is distributed on an "AS IS" BASIS,
 - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 - See the License for the specific language governing permissions and
 - limitations under the License.
 -->

<!-- 圆环进度条 -->
<template>
    <canvas
        id="canvas"
        class="canvas"
        :width="canvasWidth"
        :height="canvasWidth"
        :class="{'rtl-l': $rtl}"
    >
    </canvas>
</template>

<script>
export default {
    data() {
        return {
            canvasHeight: 12.17 * window.rem,
            ctx: null,
            progress: 0, //当前下载进度
            timer: "",
            maxDownTime:5000,
        };
    },
    watch: {
        progress: function (newProgress, oldProgress) {
            if (newProgress >= 100) {
                clearInterval(this.timer);
                this.$emit("on-download-complete");
            } else {
                this.drawCircle(newProgress);
            }
        },
    },
    props: {
        canvasWidth: {
            type: Number,
            default: 12.17 * window.rem,
        },
        strokeWidth: {
            //圆环宽度
            type: Number,
            default: 1.5 * window.rem,
        },
        centerImage: {
            //传了这个值则中心绘制该图片，否则绘制百分比进度
            type: String,
            default: "",
        },
    },
    mounted() {
        this.canvasHeight = this.canvasWidth;

        //解决锯齿
        let canvas = document.getElementById("canvas");
        this.ctx = canvas.getContext("2d");
        let width = canvas.width;
        let height = canvas.height;
        let devicePixelRatio = 1;
        if (window.devicePixelRatio) {
            // 执行抗锯齿
            devicePixelRatio = window.devicePixelRatio;
            canvas.style.width = width + "px";
            canvas.style.height = height + "px";
            canvas.height = height * devicePixelRatio;
            canvas.width = width * devicePixelRatio;
            this.ctx.scale(devicePixelRatio, devicePixelRatio);
        }
        
    },
    beforeDestroy() {
        clearInterval(this.timer);
    },
    methods: {
        initMethod(progress){
            this.maxDownTime=progress;
            this.progress=0;
            this.drawCircle(this.progress);
            clearInterval(this.timer);
            this.timer = setInterval(this.updateProgress, 1000);
        },
        drawCircle: function (progress) {
            let canvas = document.getElementById("canvas");
            if (this.ctx == null) {
                this.ctx = canvas.getContext("2d");
            }
            //初始化参数
            let centerX = this.canvasWidth / 2;
            let centerY = this.canvasHeight / 2;
            let radius = this.canvasWidth / 2 - this.strokeWidth / 2;
            let pi = Math.PI;
            let perDegreeAngle = (2 * pi) / 360; //每一度角度对应的弧度值
            let startAngle = -(perDegreeAngle * 90);
            let endAngle = startAngle + (progress / 100) * 2 * pi;
            //清空画布
            this.ctx.clearRect(0, 0, this.canvasWidth, this.canvasWidth);
            let ctx = this.ctx;
            //画底环
            ctx.save();
            ctx.beginPath();
            ctx.strokeStyle = window.isDark ? "#202224" : "rgba(0,0,0,0.03)";
            ctx.lineWidth = this.strokeWidth;
            ctx.arc(centerX, centerY, radius, 0, 2 * pi);
            ctx.stroke();
            ctx.restore();
            //画渐变色进度条
            let totalDrawAngle = endAngle - startAngle; //需要绘制的总弧长,该值越大，绘制次数应该越多
            let drawTimes = 0; //绘制次数
            let minTimes = 20; //最小绘制次数
            let angleIncrement = 0.012 * pi; //弧度增量
            let timesIncrement = 1; //绘制次数增量，每一个弧度增量增加多少次绘制
            drawTimes =
                Math.max(parseInt(totalDrawAngle / angleIncrement), 1) *
                timesIncrement;
            if (drawTimes < minTimes) {
                drawTimes = minTimes;
            }
            let startAlpha = 0.001; //起始透明度
            let endAlpha = 1; //终止透明度
            let deltaAlpha = (endAlpha - startAlpha) / (drawTimes * 2); //每一次绘制的透明度差值
            let deltaAngle = (endAngle - startAngle) / drawTimes; //每一段弧度的长度
            let tempEndAngle = 0;
            ctx.save();
            for (let i = 0; i < drawTimes; i++) {
                tempEndAngle = startAngle + deltaAngle;
                ctx.beginPath();
                ctx.lineCap = "round";
                ctx.lineJoin = "round";
                ctx.lineWidth = this.strokeWidth;
                ctx.strokeStyle =
                    "rgba(251,101,34," + (startAlpha + deltaAlpha * i) + ")";
                ctx.arc(centerX, centerY, radius, startAngle, tempEndAngle);
                ctx.stroke();
                startAngle += deltaAngle;
            }
            ctx.restore();
            //如果中心图片没有资源，则画中心进度
            if(!this.centerImage){
                let unitSize = 1.6 * window.rem;
                let percent = progress + "";
                let unitMargin = 0.3 * window.rem;
                let numSize = 3.6 * window.rem;
                let unit = "%";
                ctx.save();
                ctx.beginPath();
                ctx.fillStyle = window.isDark ? "#FFFFFF66" : "#000000";
                ctx.font = "bold " + numSize + "px HarmonyDigit";
                ctx.textAlign = "center";
                ctx.textBaseline = "middle";
                ctx.fillText(percent, centerX - unitSize / 2, centerY); //左移unit宽度的一半
                // 画百分号
                let numWidth = ctx.measureText(percent);
                ctx.beginPath();
                ctx.fillStyle = window.isDark ? "#FFFFFF66" : "#000000";
                ctx.font = "normal " + unitSize + "px HarmonyDigit";
                ctx.textAlign = "center";
                ctx.textBaseline = "middle";
                ctx.fillText(
                    unit,
                    centerX + numWidth.width / 2,
                    centerY + (numSize / 2 - unitSize)
                ); //横坐标右移num宽度的一半 纵坐标下移num高度与unit高度的差值
                ctx.restore();
            }else{
                let widthSize = 12 * window.rem;
                let heightSize = 12 * window.rem;
                let img = new Image();
                img.onload = () => {
                    centerX -= widthSize / 2;
                    centerY -= heightSize / 2;
                    this.ctx.drawImage(img, centerX, centerY, widthSize, heightSize);
                };
                img.onerror = function (x) {
                    console.info("img load error" + JSON.stringify(x));
                };
                img.src = this.centerImage;
            }
        },
        measureFailed: function () {
            let progress = this.progress;
            let canvas = document.getElementById("canvas");
            if (this.ctx == null) {
                this.ctx = canvas.getContext("2d");
            }
            //初始化参数
            let centerX = this.canvasWidth / 2;
            let centerY = this.canvasHeight / 2;
            let radius = this.canvasWidth / 2 - this.strokeWidth / 2;
            let pi = Math.PI;
            let perDegreeAngle = (2 * pi) / 360; //每一度角度对应的弧度值
            let startAngle = -(perDegreeAngle * 90);
            let endAngle = startAngle + (progress / 100) * 2 * pi;
            //清空画布
            this.ctx.clearRect(0, 0, this.canvasWidth, this.canvasWidth);
            let ctx = this.ctx;
            //画底环
            ctx.save();
            ctx.beginPath();
            ctx.strokeStyle = window.isDark ? "#202224" : "rgba(0,0,0,0.03)";
            ctx.lineWidth = this.strokeWidth;
            ctx.arc(centerX, centerY, radius, 0, 2 * pi);
            ctx.stroke();
            ctx.restore();
            //画中心图片
            let widthSize = 12 * window.rem;
            let heightSize = 12 * window.rem;
            let img = new Image();
            img.onload = () => {
                centerX -= widthSize / 2;
                centerY -= heightSize / 2;
                this.ctx.drawImage(img, centerX, centerY, widthSize, heightSize);
            };
            img.onerror = function (x) {
                console.info("img load error" + JSON.stringify(x));
            };
            img.src = this.centerImage;
            clearInterval(this.timer);
            this.$emit("on-download-error");
        },
        updateProgress: function () {
            this.progress += (100/(this.maxDownTime/1000));
            this.drawCircle(this.progress);
        },
        getProgress: function () {
            return this.progress;
        },
        retry: function () {
            this.progress = 0;
            this.drawCircle(this.progress);
            this.timer = setInterval(this.updateProgress, 500);
        },
    },
};
</script>

<style>
.canvas {
    width: 12.17rem;
    height: 12.17rem;
}
</style>